package com.qnnproject

import android.content.Context
import android.util.Log
import com.google.gson.Gson
import com.google.gson.JsonSyntaxException
import com.rabbitmq.client.*
import java.io.IOException
import java.util.concurrent.TimeoutException

class RabbitMQService(
    private val context: Context,
    private val onMessageReceived: (CallTaskMessage) -> Unit
) {
    
    companion object {
        private const val TAG = "RabbitMQService"
        private const val HOST = "192.168.1.11"
        private const val USERNAME = "admin"
        private const val PASSWORD = "111111"
        private const val VIRTUAL_HOST = "/"
        private const val PORT = 5672
    }
    
    private var connection: Connection? = null
    private var channel: Channel? = null
    private var consumer: DefaultConsumer? = null
    private val gson = Gson()
    private val deviceIdManager = DeviceIdManager(context)
    private var isConnected = false
    
    /**
     * 连接到RabbitMQ
     */
    fun connect() {
        try {
            Log.d(TAG, "正在连接到RabbitMQ...")
            
            val factory = ConnectionFactory()
            factory.host = HOST
            factory.port = PORT
            factory.username = USERNAME
            factory.password = PASSWORD
            factory.virtualHost = VIRTUAL_HOST
            factory.isAutomaticRecoveryEnabled = true
            factory.networkRecoveryInterval = 10000 // 10秒
            
            connection = factory.newConnection()
            channel = connection?.createChannel()
            
            if (channel != null) {
                setupQueue()
                startConsuming()
                isConnected = true
                Log.d(TAG, "RabbitMQ连接成功")
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "RabbitMQ连接失败", e)
            isConnected = false
        }
    }
    
    /**
     * 设置队列
     */
    private fun setupQueue() {
        try {
            val queueName = deviceIdManager.getQueueName()
            Log.d(TAG, "设置队列: $queueName")
            
            // 声明队列，如果不存在则创建
            channel?.queueDeclare(queueName, true, false, false, null)
            
        } catch (e: Exception) {
            Log.e(TAG, "设置队列失败", e)
        }
    }
    
    /**
     * 开始消费消息
     */
    private fun startConsuming() {
        try {
            val queueName = deviceIdManager.getQueueName()
            
            consumer = object : DefaultConsumer(channel) {
                override fun handleDelivery(
                    consumerTag: String?,
                    envelope: Envelope?,
                    properties: AMQP.BasicProperties?,
                    body: ByteArray?
                ) {
                    try {
                        val message = String(body ?: byteArrayOf(), Charsets.UTF_8)
                        Log.d(TAG, "收到消息: $message")
                        
                        // 解析JSON消息
                        val callTaskMessage = gson.fromJson(message, CallTaskMessage::class.java)
                        
                        // 验证设备ID是否匹配
                        if (callTaskMessage.deviceId == deviceIdManager.getDeviceId()) {
                            Log.d(TAG, "设备ID匹配，处理拨号任务")
                            onMessageReceived(callTaskMessage)
                        } else {
                            Log.w(TAG, "设备ID不匹配，忽略消息")
                        }
                        
                        // 确认消息
                        channel?.basicAck(envelope?.deliveryTag ?: 0, false)
                        
                    } catch (e: JsonSyntaxException) {
                        Log.e(TAG, "JSON解析失败", e)
                        // 拒绝消息
                        channel?.basicNack(envelope?.deliveryTag ?: 0, false, false)
                    } catch (e: Exception) {
                        Log.e(TAG, "处理消息失败", e)
                        // 拒绝消息
                        channel?.basicNack(envelope?.deliveryTag ?: 0, false, false)
                    }
                }
            }
            
            // 开始消费
            channel?.basicConsume(queueName, false, consumer)
            Log.d(TAG, "开始监听队列: $queueName")
            
        } catch (e: Exception) {
            Log.e(TAG, "开始消费失败", e)
        }
    }
    
    /**
     * 断开连接
     */
    fun disconnect() {
        try {
            consumer = null
            channel?.close()
            connection?.close()
            isConnected = false
            Log.d(TAG, "RabbitMQ连接已断开")
        } catch (e: Exception) {
            Log.e(TAG, "断开连接失败", e)
        }
    }
    
    /**
     * 检查连接状态
     */
    fun isConnected(): Boolean {
        return isConnected && connection?.isOpen == true && channel?.isOpen == true
    }
    
    /**
     * 获取设备ID
     */
    fun getDeviceId(): String {
        return deviceIdManager.getDeviceId()
    }
    
    /**
     * 获取队列名称
     */
    fun getQueueName(): String {
        return deviceIdManager.getQueueName()
    }
}
